package yz.cp.back.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;
import yz.cp.back.admin.vo.SysRoleAddVo;
import yz.cp.back.admin.vo.SysRoleEditVo;
import yz.cp.back.common.base.BaseController;
import yz.cp.back.common.res.ApiResult;
import yz.cp.back.common.utils.PageKit;
import yz.cp.back.s.entity.SysRole;
import yz.cp.back.s.entity.SysRoleDepartment;
import yz.cp.back.s.entity.SysRolePermission;
import yz.cp.back.s.entity.SysUserRole;
import yz.cp.back.s.service.ISysRoleDepartmentService;
import yz.cp.back.s.service.ISysRolePermissionService;
import yz.cp.back.s.service.ISysRoleService;
import yz.cp.back.s.service.ISysUserRoleService;

import java.util.List;
import java.util.Set;


/**
 * 角色管理接口
 * @author xukk
 */
@Slf4j
@RestController
@RequestMapping("/web/role")
public class RoleController extends BaseController {

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysUserRoleService userRoleService;

    @Autowired
    private ISysRolePermissionService rolePermissionService;

    @Autowired
    private ISysRoleDepartmentService roleDepartmentService;


    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 获取全部角色
     * @return
     */
    @RequestMapping(value = "/getAllList",method = RequestMethod.GET)
    public ApiResult roleGetAll(){
        List<SysRole> list = roleService.list();
        return renderOk().add(list);
    }

    /**
     * 分页获取角色
     * @param pageable
     * @return
     */
    @RequestMapping(value = "/getAllByPage",method = RequestMethod.GET)
    public ApiResult getRoleByPage(@PageableDefault Pageable pageable){
        QueryWrapper wrapper=new QueryWrapper<SysRole>();
        IPage<SysRole> list = roleService.page(PageKit.buildPage(pageable,wrapper),wrapper);
        for(SysRole role : list.getRecords()){
            // 角色拥有权限
            List<SysRolePermission> permissions = rolePermissionService.findByRoleId(role.getId());
            role.setPermissions(permissions);
            // 角色拥有数据权限
            List<SysRoleDepartment> departments = roleDepartmentService.findByRoleId(role.getId());
            role.setDepartments(departments);
        }
        return renderOk().add(list);
    }

    /**
     * 设置或取消默认角色
     * @param id
     * @param isDefault
     * @return
     */
    @RequestMapping(value = "/setDefault",method = RequestMethod.POST)
    public ApiResult setDefault(@RequestParam String id,
                                @RequestParam Boolean isDefault){

        SysRole role = roleService.getById(id);
        if(role==null){
            return renderError("角色不存在");
        }
        SysRole updateRole=new SysRole();
        updateRole.setId(role.getId());
        updateRole.setDefaultRole(isDefault);
        roleService.updateById(updateRole);
        return renderOk("设置成功");
    }

    /**
     * 编辑角色分配菜单权限
     * @param roleId
     * @param permIds
     * @return
     */
    @RequestMapping(value = "/editRolePerm",method = RequestMethod.POST)
    public ApiResult editRolePerm(@RequestParam String roleId,
                                  @RequestParam(required = false) String[] permIds){

        //删除其关联权限
        rolePermissionService.deleteByRoleId(roleId);
        //分配新权限
        for(String permId : permIds){
            SysRolePermission rolePermission = new SysRolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permId);
            rolePermissionService.save(rolePermission);
        }
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        Set<String> keysUserPerm = redisTemplate.keys("userPermission:" + "*");
        redisTemplate.delete(keysUserPerm);
        Set<String> keysUserMenu = redisTemplate.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        return renderOk();
    }

    /**
     * 编辑角色分配数据权限
     * @param roleId
     * @param dataType
     * @param depIds
     * @return
     */
    @RequestMapping(value = "/editRoleDep",method = RequestMethod.POST)
    public ApiResult editRoleDep(@RequestParam String roleId,
                                 @RequestParam Integer dataType,
                                 @RequestParam(required = false) String[] depIds){

        SysRole r = roleService.getById(roleId);
        if(r==null){
            return renderError("角色不存在");
        }
        SysRole updateRole=new SysRole();
        updateRole.setId(r.getId());
        updateRole.setDataType(dataType);
        roleService.updateById(updateRole);
        // 删除其关联数据权限
        roleDepartmentService.deleteByRoleId(roleId);
        // 分配新数据权限
        for(String depId : depIds){
            SysRoleDepartment roleDepartment = new SysRoleDepartment();
            roleDepartment.setRoleId(roleId);
            roleDepartment.setDepartmentId(depId);
            roleDepartmentService.save(roleDepartment);
        }
        // 手动删除相关缓存
        Set<String> keys = redisTemplate.keys("department:" + "*");
        redisTemplate.delete(keys);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);

        return renderOk();
    }

    /**
     * 保存数据
     * @param role
     * @return
     */
    @RequestMapping(value = "/save",method = RequestMethod.POST)
    public ApiResult save(@ModelAttribute SysRoleAddVo vo){
        SysRole role=beanMapper.map(vo,SysRole.class);
        roleService.save(role);
        return renderOk();
    }

    /**
     * 更新数据
     * @param vo
     * @return
     */
    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    public ApiResult edit(@ModelAttribute SysRoleEditVo vo){
        SysRole entity=beanMapper.map(vo,SysRole.class);
        if(entity.getId()==null){
            return renderError("缺少主键");
        }
        roleService.updateById(entity);
        //手动批量删除缓存
        Set<String> keysUser = redisTemplate.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserRole = redisTemplate.keys("userRole:" + "*");
        redisTemplate.delete(keysUserRole);
        return renderOk();
    }

    /**
     * 批量通过ids删除
     * @param ids
     * @return
     */
    @RequestMapping(value = "/delAllByIds/{ids}",method = RequestMethod.DELETE)
    public ApiResult delByIds(@PathVariable String[] ids){

        for(String id:ids){
            List<SysUserRole> list = userRoleService.findByRoleId(id);
            if(list!=null&&list.size()>0){
                return  renderError("删除失败，包含正被用户使用关联的角色");
            }
        }
        for(String id:ids){
            roleService.removeById(id);
            //删除关联菜单权限
            rolePermissionService.deleteByRoleId(id);
            //删除关联数据权限
            roleDepartmentService.deleteByRoleId(id);
        }
        return renderOk("批量通过id删除数据成功");
    }

}
